package com.atguigu.gulimall.product.web;

import com.atguigu.gulimall.product.config.MyRedissonConfig;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.Catelog2VO;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RSemaphore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author kabuda
 * @create 2022-11-17 19:43
 */
@Controller
public class IndexController {
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private MyRedissonConfig redisson;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping(value = {"/","/index.html"})
    public String indexPage(Model model){
        List<CategoryEntity> categoryEntities= categoryService.getLevel1Categorys();
        model.addAttribute("categorys",categoryEntities);
        return "index";
    }

    // index/catalog.json
    @ResponseBody
    @GetMapping("/index/catalog.json")
    public Map<String,List<Catelog2VO>> getCatalogJson(){
        Map<String,List<Catelog2VO>>  map =categoryService.getCatalogJson();
        return map;
    }

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return  "hello";
    }

    @ResponseBody
    @RequestMapping("/lock")
    public String lock(){
        //获取一把锁，只要名字一致，锁就一致
        RLock lock = redisson.redissonClient().getLock("my-lock");
        //加锁，阻塞时等待（没锁就一直等待，拿到锁再进去）
        //默认锁有效时30秒，如果业务超长TTL会自动续期（看门狗）
        lock.lock();
        //加锁，有效时间时间为10秒，不会自动续期
        //lock.lock(10, TimeUnit.SECONDS);
        try {
            System.out.println("加锁成功，执行业务....."+Thread.currentThread().getName());
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }finally {
            //解锁
            lock.unlock();
            System.out.println("释放锁....."+Thread.currentThread().getName());

        }

        return "redisson锁";
    }

    @RequestMapping("/write")
    @ResponseBody
    public String write(){
        RReadWriteLock lock = redisson.redissonClient().getReadWriteLock("rw-lock");
        RLock wLock = lock.writeLock();
        wLock.lock();
        try {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //写操作
            String s = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set("text",s);
            return s;
        }finally {
            wLock.unlock();
        }
    }
    @RequestMapping("/read")
    @ResponseBody
    public String read(){
        RReadWriteLock lock = redisson.redissonClient().getReadWriteLock("rw-lock");
        RLock rLock = lock.readLock();
        rLock.lock();
        try {
            //读取业务
            String text = redisTemplate.opsForValue().get("text");
            return text;
        }finally {
            rLock.unlock();
        }
    }
    @RequestMapping("/park")
    @ResponseBody
    public String park() throws InterruptedException {
        RSemaphore park = redisson.redissonClient().getSemaphore("park");
        boolean b = park.tryAcquire();//获取一个信号量（redis对应key的value-1）
        if(b){
            //执行业务
        }else{
            return "error";
        }
        return "ok";
    }
    @RequestMapping("/go")
    @ResponseBody
    public String go() throws InterruptedException {
        RSemaphore park = redisson.redissonClient().getSemaphore("park");
        park.release();  //释放一个信号量（redis对应key的value+1）
        return "ok";
    }
    //第五人格必须五个人都载入游戏页面才能开始游戏
    @RequestMapping("/play")
    @ResponseBody
    public String play() throws InterruptedException {
        RCountDownLatch count = redisson.redissonClient().getCountDownLatch("第五人格");
        //设置数为5
        count.trySetCount(5);
        count.await();//等待闭锁完成
        return "开始游戏";
    }
    @RequestMapping("/gogogo/{id}")
    @ResponseBody
    public String gogogo(@PathVariable("id") Long id)  {
        RCountDownLatch count = redisson.redissonClient().getCountDownLatch("第五人格");
        count.countDown(); //计数-1
        return id+"载入游戏";
    }

}
